package com.softer.chengxin.scheduled.controller;

import com.softer.chengxin.common.domin.Common;
import com.softer.chengxin.common.domin.CommonResult;
import com.softer.chengxin.common.enums.ResultEnum;
import com.softer.chengxin.common.util.DateFormatUtil;
import com.softer.chengxin.scheduled.TaskRunnable;
import com.softer.chengxin.scheduled.dao.ScheduledTaskDao;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpSession;
import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.ScheduledFuture;

/**
 * @author Gong Zhiyang
 * @date 2019/1/18
 */
@RestController
public class DynamicScheduledController implements ApplicationRunner {

    private Logger logger = LoggerFactory.getLogger(DynamicScheduledController.class);
    @Autowired
    ScheduledTaskDao scheduledTaskDao;
    @Autowired
    private ThreadPoolTaskScheduler threadPoolTaskScheduler;
    private ScheduledFuture<?> future;

    @Bean
    public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
        return new ThreadPoolTaskScheduler();
    }

    /**
     * 停止定时任务
     *
     * @return
     */
    @PostMapping("/api/scheduled/stopCron")
    public CommonResult stopCron() {
        if (future != null) {
            future.cancel(true);
            return new CommonResult(ResultEnum.SUCCESS.getCode(), Common.OPERATE_SUCCESS);
        }
        return new CommonResult(ResultEnum.FAIL.getCode(), Common.OPERATE_FAIL);
    }

    /**
     * 更新定时任务时间
     *
     * @param time    时间
     * @param session 缓存
     * @return 更新结果
     */
    @PostMapping("/api/scheduled/updateCron")
    public CommonResult updateCron(String time, HttpSession session) {
        String loginName = (String) session.getAttribute(Common.LOGIN_NAME);
        if (StringUtils.isBlank(loginName)) {
            return new CommonResult(ResultEnum.FAIL.getCode(), "请重新登陆后设置");
        }
        scheduledTaskDao.addTime(time, loginName);
        stopCron();// 先停止，在开启.
        String cron = getCron(time);
        future = threadPoolTaskScheduler.schedule(new TaskRunnable(), new CronTrigger(cron));
        logger.info("更新定时任务时间:{},操作人:{}", time, loginName);
        return new CommonResult(ResultEnum.SUCCESS.getCode(), Common.OPERATE_SUCCESS);
    }

    /**
     * 获取定时任务参数
     *
     * @param time 设定的时间
     * @return 定时器参数
     * @throws ParseException
     */
    private String getCron(String time) {
        try {
            Calendar c = DateFormatUtil.getCalender(time);
            int month = c.get(Calendar.MONTH) + 1;
            int day = c.get(Calendar.DATE);
            StringBuffer cron = new StringBuffer(10);
            cron.append("59 59 23  ").append(day).append(" ").append(month).append(" ?");
            return cron.toString();
        } catch (Exception e) {
            logger.error("设置定时任务异常", e);
        }
        return "59 59 23  31 3 ?";
    }

    /**
     * 程序启动时加载任务
     *
     * @param args
     * @throws Exception
     */
    @Override
    public void run(ApplicationArguments args) throws Exception {
        // 获取最近一次设定的时间
        String time = scheduledTaskDao.getTime();
        logger.info("初始化定时任务时间:" + time);
        String cron = getCron(time);
        future = threadPoolTaskScheduler.schedule(new TaskRunnable(), new CronTrigger(cron));
    }
}
